package com.open.api.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.open.api.bo.RequestBO;
import com.open.api.client.ApiClient;
import com.open.api.model.ResultModel;
import com.open.api.util.BeanUtils;
import com.open.api.util.SystemClock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * 统一网关
 */
@RestController
@RequestMapping("/open")
public class OpenApiController {

    private static final Logger LOGGER = LoggerFactory.getLogger(OpenApiController.class);

    @Autowired
    private ApiClient apiClient;

    /**
     * 统一网关入口
     *
     * @param method       请求方法
     * @param version      版本
     * @param apiRequestId 请求标识（用于日志中分辨是否是同一次请求）
     * @param charset      请求编码
     * @param signType     签名格式
     * @param sign         签名
     * @param content      业务内容参数
     */
    @PostMapping("/gateway")
   /* public ResultModel gateway(@RequestParam(value = "app_id", required = true) String appId,
                               @RequestParam(value = "method", required = true) String method,
                               @RequestParam(value = "version", required = true) String version,
                               @RequestParam(value = "api_request_id", required = true) String apiRequestId,
                               @RequestParam(value = "charset", required = true) String charset,
                               @RequestParam(value = "sign_type", required = true) String signType,
                               @RequestParam(value = "sign", required = true) String sign,
                               @RequestParam(value = "content", required = true) String content,
                               HttpServletRequest request) throws Throwable {
*/
    public ResultModel gateway(@RequestBody JSONObject param , HttpServletRequest request) throws Throwable {
        //Map<String, Object> params = WebUtils.getParametersStartingWith(request, StringPool.EMPTY);
        RequestBO requestBO=JSON.toJavaObject(param,RequestBO.class);
        String appId=requestBO.getApp_id();
        String method=requestBO.getMethod();
        String apiRequestId=requestBO.getApi_request_id();
        String charset=requestBO.getCharset();
        String signType=requestBO.getSign_type();
        String content=requestBO.getContent();

        Map<String, Object> params = BeanUtils.beanToMap(requestBO);

        LOGGER.info("【{}】>> 网关执行开始 >> method={} params = {}", appId, method,param);

        long start = SystemClock.millisClock().now();

        ResultModel resultModel=new ResultModel();

        if(apiRequestId.isEmpty()){
            resultModel.setSuccess(false);
            resultModel.setErrorCode("1");
            resultModel.setErrorMsg("api_request_id参数不能为空");
            return  resultModel;
        }
        //验签
        resultModel=apiClient.checkSign(params, appId, charset, signType);

        if(!resultModel.isSuccess()){
            return  resultModel;
        }

        if(apiRequestId.equals("2")){
            content=JSON.toJSONString(content);
        }else if(apiRequestId.equals("1")){

        }else{
            resultModel.setSuccess(false);
            resultModel.setErrorCode("1");
            resultModel.setErrorMsg("api_request_id参数不正确");
            return  resultModel;
        }

        //请求接口
        ResultModel result = apiClient.invoke(method, appId, content);

        LOGGER.info("【{}】>> 网关执行结束 >> method={},result = {}, times = {} ms",
                appId, method, JSON.toJSONString(result), (SystemClock.millisClock().now() - start));

        return result;
    }

}
